/********************************************************************
 * 项目名称                ：rochoc<p>
 * 包名称                  ：com.rochoc.autoupdate<p>
 * 文件名称                ：AutoUpdateClient.java<p>
 * 编写者                 ：kfzx-luoc<p>
 * 编写日期                ：2008-12-23<p>
 * 程序功能（类）描述    ：<p>
 * 自动升级客户端对像
 * 程序变更日期            ：
 * 变更作者                ：
 * 变更说明                ：
 ********************************************************************/
package com.abigdreamer.net.p2p;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

/**
 * @author kfzx-luoc
 */
public class FileReceiver implements Runnable {

	private Socket socket = null;
	private OutputStream socketOut;
	private InputStream socketIn;
	private FileProcessListener listener;
	private int fileSize;
	private String filePath;

	public FileReceiver(String ip, int port,String filePath, int fileSize, FileProcessListener listener) {
		try {
			System.out.println("服务器：" + ip + ",端口："  + port);
			
			this.filePath = filePath;
			this.listener = listener;
			this.fileSize = fileSize;
			
			socket = new Socket(ip, port);
			socket.setSoTimeout(30000);// 30秒
		} catch (Exception e) {
			Config.print("创建与自动升级服务器之间的连接失败," + e);
			e.printStackTrace();
		}
	}

	public void run() {
		if (socket == null) {
			Config.print("无法与服务器连接，升级失败");
			return;
		}
		try {
			socketOut = socket.getOutputStream();
			socketIn = socket.getInputStream();

			// 发送本地版本信息给服务器
			socketOut.write(Config.packingCmd(AUPD.READY_TO_UPDATE));// 发送传输版本信息命令
			socketOut.flush();
			
			while (true) {

				String cmd = FileContract.unpackingCmd(socketIn);
				if (cmd == null) {
					socketOut.write(Config.packingCmd(AUPD.BYE));// 结束
					break;
				}

				if (cmd.equals(AUPD.START_TRANSMIT)) {// 接收文件
					if (receiveFile(filePath)) {
						socketOut.write(Config.packingCmd(AUPD.TERMINATE_TRANSMIT));
					} else {
						socketOut.write(Config.packingCmd(AUPD.BYE));
					}
				} else if (cmd.equals(AUPD.UPDATED_FAILURE)) {// 更新失败
					Config.print("文件传输失败");
					socketOut.write(Config.packingCmd(AUPD.BYE));// 结束
					break;
				} else if (cmd.equals(AUPD.UPDATED_SUCCESSFUL)) {// 更新成功
					Config.print("文件传输成功");
					socketOut.write(Config.packingCmd(AUPD.BYE));// 结束
					break;
				} else if (cmd.equals(AUPD.BYE)) {// 结束链接
					socketOut.write(Config.packingCmd(AUPD.BYE));// 结束
					break;
				}
			}// END while(true)

			// 关闭资源及链接
			socketOut.close();
			socketIn.close();
			socket.close();
			Config.print("文件传输完毕");
		} catch (Exception e) {
			Config.print("文件传输失败," + e);
			e.printStackTrace();
		}
	}

	private boolean receiveFile(String currFileAbs) {
		try {
			if (currFileAbs == null || currFileAbs.equals("")) {
				Config.print("无法获取更新文件信息，更新失败");
				return false;
			}

			File file = new File(currFileAbs);
			FileOutputStream fout = new FileOutputStream(file);
			
			byte[] resultData = FileContract.unpacking(socketIn, fout, fileSize/1024, listener);
			
			if (resultData != null) {
				
				fout.write(resultData);
				Config.print("成功传输文件：" + file.getAbsolutePath());
				fout.flush();
				fout.close();
				return true;
			} else {
				fout.flush();
				fout.close();
				
				Config.print("传输文件：" + currFileAbs + "成功");
				return true;
			}
		} catch (Exception e) {
			Config.print("传输文件'" + currFileAbs + "'失败," + e);
			e.printStackTrace();
			return false;
		}
	}

	// 测试主流程
	public static void main(String args[]) throws IOException {
//		FileReceiver client = new FileReceiver("127.0.0.1", 9009,null,null);
//		client.receive("");
	}
}